import {
  formatDisplayValue,
  createUpdateDataFunction,
  getTargetAndPath,
} from "./utils.mjs";
import { createArrayItem, initializeNewItem } from "./array_helpers.mjs";
import { thin } from "../../thin3/thin3.mjs";
import {
  BaseRenderer,
  InputRenderers,
  SelectRenderer,
  ObjectRenderer,
  ArrayRenderer,
} from "./renderers/index.mjs";

// 在文件开头添加样式
const style = document.createElement("style");
style.textContent = `
  json_property label.required::after {
    content: "*";
    color: red;
    margin-left: 4px;
  }

  json_property input.invalid,
  json_property textarea.invalid,
  json_property select.invalid {
    border-color: red;
    background-color: #fff0f0;
  }

  json_property input[required],
  json_property textarea[required],
  json_property select[required] {
    border-left: 3px solid #ff9800;
  }
`;
document.head.appendChild(style);

/**
 * 渲染器模块
 * 提供各种类型的渲染函数，包括对象、属性和数组单元格的渲染
 */

/**
 * 渲染对象
 * 创建对象容器并渲染其所有属性
 *
 * @param {Object} params 参数对象
 * @param {HTMLElement} params.container 容器元素
 * @param {Object} params.schema Schema 定义
 * @param {*} params.data 对象数据
 * @param {string} params.mode 显示模式
 */
export function render_object({ container, schema, data, mode }) {
  const wrapper = document.createElement("json_object");

  if (schema.title) {
    const title = document.createElement("h3");
    title.textContent = schema.title;
    wrapper.appendChild(title);
  }

  if (schema.description) {
    const description = document.createElement("p");
    description.className = "description";
    description.textContent = schema.description;
    wrapper.appendChild(description);
  }

  // 渲染所有属性
  if (schema.properties) {
    Object.entries(schema.properties).forEach(([name, propSchema]) => {
      render_property({
        container: wrapper,
        schema: {
          ...propSchema,
          name,
          path: schema.path ? `${schema.path}/${name}` : name,
          parent: schema, // 传递父对象信息
        },
        data: data?.[name],
        mode,
      });
    });
  }

  container.appendChild(wrapper);
}

/**
 * 渲染属性
 * 根据 schema 类型创建不同的输入控件
 *
 * @param {Object} params 参数对象
 * @param {HTMLElement} params.container 容器元素
 * @param {Object} params.schema Schema 定义
 * @param {*} params.data 属性数据
 * @param {string} params.mode 显示模式
 */
export function render_property({ container, schema, data, mode }) {
  const wrapper = document.createElement("json_property");
  wrapper.path = schema.path;

  // 检查该属性是否是必填的
  const isRequired =
    schema.thin?.required !== undefined
      ? schema.thin.required
      : schema.parent &&
        schema.parent.required &&
        schema.parent.required.includes(schema.name);

  // 创建属性标签
  if (schema.type !== "object") {
    const label = BaseRenderer.createPropertyLabel(schema);
    if (isRequired) {
      label.classList.add("required");
    }
    wrapper.appendChild(label);
  }

  // 只读模式下的简单类型处理
  if (mode === "read" && schema.type !== "object" && schema.type !== "array") {
    wrapper.appendChild(BaseRenderer.createReadOnlyElement(schema, data));
    container.appendChild(wrapper);
    return;
  }

  // 创建数据更新函数
  const updateData = createUpdateDataFunction(
    container,
    schema.path || schema.name
  );

  // 处理特殊的 thin 类型
  if (schema.thin?.type) {
    if (schema.thin.type === "textarea") {
      const textarea = InputRenderers.createTextarea(schema, data, updateData);
      if (isRequired) {
        textarea.required = true;
        textarea.setAttribute("aria-required", "true");
      }
      BaseRenderer.handleWidthConfig(textarea, schema);
      wrapper.appendChild(textarea);
    } else if (schema.thin.type === "select") {
      SelectRenderer.createSelect(schema, data, updateData).then((select) => {
        if (isRequired) {
          select.required = true;
          select.setAttribute("aria-required", "true");
        }
        wrapper.appendChild(select);
      });
    } else {
      const input = InputRenderers.createSpecialInput(schema, data, updateData);
      if (isRequired) {
        input.required = true;
        input.setAttribute("aria-required", "true");
      }
      wrapper.appendChild(input);
    }
  } else {
    // 根据 JSON Schema 类型创建控件
    if (!schema.type) {
      const textarea = document.createElement("textarea");
      textarea.value = data ? JSON.stringify(data, null, 2) : "";
      if (isRequired) {
        textarea.required = true;
        textarea.setAttribute("aria-required", "true");
      }
      textarea.onchange = (e) => {
        try {
          const value = JSON.parse(e.target.value);
          updateData(value);
          textarea.classList.remove("error");
        } catch (err) {
          textarea.classList.add("error");
        }
      };
      wrapper.appendChild(textarea);
    } else {
      switch (schema.type) {
        case "string":
          const textInput = InputRenderers.createTextInput(
            schema,
            data,
            updateData
          );
          if (isRequired) {
            textInput.required = true;
            textInput.setAttribute("aria-required", "true");
          }
          wrapper.appendChild(textInput);
          break;
        case "number":
        case "integer":
          const numberInput = InputRenderers.createNumberInput(
            schema,
            data,
            updateData
          );
          if (isRequired) {
            numberInput.required = true;
            numberInput.setAttribute("aria-required", "true");
          }
          wrapper.appendChild(numberInput);
          break;
        case "boolean":
          const booleanInput = InputRenderers.createBooleanInput(
            schema,
            data,
            updateData
          );
          wrapper.appendChild(booleanInput);
          break;
        case "object":
          render_object({
            container: wrapper,
            schema: { ...schema, title: schema.name },
            data,
            mode,
          });
          break;
        case "array":
          ArrayRenderer.render({ container: wrapper, schema, data, mode });
          break;
        default:
          const span = document.createElement("span");
          span.textContent = data || "";
          wrapper.appendChild(span);
      }
    }
  }

  container.appendChild(wrapper);
}

/**
 * 渲染数组单元格
 * 在表格中渲染单个单元格的内容
 *
 * @param {Object} params 参数对象
 * @param {HTMLElement} params.container 容器元素
 * @param {Object} params.schema Schema 定义
 * @param {*} params.data 单元格数据
 * @param {Function} params.updateData 数据更新函数
 * @param {string} params.mode 显示模式
 */
export function render_array_cell({
  container,
  schema,
  data,
  updateData,
  mode,
}) {
  const cell = document.createElement("json_property");

  // 只读模式的处理
  if (mode === "read") {
    if (schema.type === "object") {
      render_object({
        container: cell,
        schema: { ...schema, title: schema.name },
        data,
        mode,
      });
    } else {
      cell.appendChild(BaseRenderer.createReadOnlyElement(schema, data));
    }
    container.appendChild(cell);
    return;
  }

  // 编辑模式的处理
  if (schema.thin?.type) {
    if (schema.thin.type === "textarea") {
      const textarea = InputRenderers.createTextarea(schema, data, updateData);
      BaseRenderer.handleWidthConfig(cell, schema);
      cell.appendChild(textarea);
    } else if (schema.thin.type === "select") {
      SelectRenderer.createSelect(schema, data, updateData).then((select) => {
        cell.appendChild(select);
      });
    } else {
      cell.appendChild(
        InputRenderers.createSpecialInput(schema, data, updateData)
      );
    }
  } else {
    switch (schema.type) {
      case "string":
        cell.appendChild(
          InputRenderers.createTextInput(schema, data, updateData)
        );
        break;
      case "number":
      case "integer":
        cell.appendChild(
          InputRenderers.createNumberInput(schema, data, updateData)
        );
        break;
      case "boolean":
        cell.appendChild(
          InputRenderers.createBooleanInput(schema, data, updateData)
        );
        break;
      case "object":
        render_object({
          container: cell,
          schema: { ...schema, title: schema.name },
          data,
          mode,
        });
        break;
      default:
        const span = document.createElement("span");
        span.textContent = data || "";
        cell.appendChild(span);
    }
  }

  container.appendChild(cell);
}

/**
 * 渲染数组
 * 创建数组容器并渲染其所有元素
 *
 * @param {Object} params 参数对象
 * @param {HTMLElement} params.container 容器元素
 * @param {Object} params.schema Schema 定义
 * @param {*} params.data 数组数据
 * @param {string} params.mode 显示模式
 */
export function render_array(params) {
  ArrayRenderer.render(params);
}

async function createSelect(schema, data, updateData) {
  const select = document.createElement("select");

  // 如果配置了 ajax
  if (schema.thin.ajax) {
    const ajax = schema.thin.ajax;
    try {
      // 使用 thin.ajax 发起请求
      const response = await thin.ajax({
        url: ajax.url,
        method: ajax.method || "get",
      });

      // 从响应中获取数据
      let options = response;
      if (ajax.datapath) {
        ajax.datapath.split(".").forEach((path) => {
          options = options[path];
        });
      }

      // 添加空选项（如果不是必填）
      if (!schema.required) {
        const emptyOption = document.createElement("option");
        emptyOption.value = "";
        emptyOption.textContent = "-- 请选择 --";
        select.appendChild(emptyOption);
      }

      // 添加从服务器获取的选项
      options?.forEach((option) => {
        const optionEl = document.createElement("option");
        // 处理文本和值的模板
        optionEl.value = processTemplate(ajax.value, option);
        optionEl.textContent = processTemplate(ajax.text, option);
        select.appendChild(optionEl);
      });
    } catch (error) {
      console.error("Failed to load select options:", error);
    }
  } else if (schema.thin.options) {
    // 原有的静态选项处理逻辑保持不变
    const options = schema.thin.options || [];

    if (!schema.required) {
      const emptyOption = document.createElement("option");
      emptyOption.value = "";
      emptyOption.textContent = "-- 请选择 --";
      select.appendChild(emptyOption);
    }

    options.forEach((option) => {
      const optionEl = document.createElement("option");
      if (typeof option === "object") {
        optionEl.value = option.value;
        optionEl.textContent = option.label || option.value;
      } else {
        optionEl.value = option;
        optionEl.textContent = option;
      }
      select.appendChild(optionEl);
    });
  }

  select.value = data || "";
  select.onchange = (e) => updateData(e.target.value);
  return select;
}

// 添加模板处理函数
function processTemplate(template, data) {
  if (!template) return "";
  return template.replace(/\[\[(.*?)\]\]/g, (match, key) => {
    return data[key] || "";
  });
}
